home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Python / marshal.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  15.0 KB  |  784 lines

  1. /* Write Python objects to files and read them back.
  2.    This is intended for writing and reading compiled Python code only;
  3.    a true persistent storage facility would be much harder, since
  4.    it would have to take circular links and sharing into account. */
  5.  
  6. #include "Python.h"
  7. #include "longintrepr.h"
  8. #include "compile.h"
  9. #include "marshal.h"
  10.  
  11. #define TYPE_NULL    '0'
  12. #define TYPE_NONE    'N'
  13. #define TYPE_ELLIPSIS   '.'
  14. #define TYPE_INT    'i'
  15. #define TYPE_INT64    'I'
  16. #define TYPE_FLOAT    'f'
  17. #define TYPE_COMPLEX    'x'
  18. #define TYPE_LONG    'l'
  19. #define TYPE_STRING    's'
  20. #define TYPE_TUPLE    '('
  21. #define TYPE_LIST    '['
  22. #define TYPE_DICT    '{'
  23. #define TYPE_CODE    'c'
  24. #define TYPE_UNICODE    'u'
  25. #define TYPE_UNKNOWN    '?'
  26.  
  27. typedef struct {
  28.     FILE *fp;
  29.     int error;
  30.     /* If fp == NULL, the following are valid: */
  31.     PyObject *str;
  32.     char *ptr;
  33.     char *end;
  34. } WFILE;
  35.  
  36. #define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
  37.               else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
  38.                else w_more(c, p)
  39.  
  40. #include "protos/marshal.h"
  41.  
  42. static void
  43. w_more(c, p)
  44.     char c;
  45.     WFILE *p;
  46. {
  47.     int size, newsize;
  48.     if (p->str == NULL)
  49.         return; /* An error already occurred */
  50.     size = PyString_Size(p->str);
  51.     newsize = size + 1024;
  52.     if (_PyString_Resize(&p->str, newsize) != 0) {
  53.         p->ptr = p->end = NULL;
  54.     }
  55.     else {
  56.         p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
  57.         p->end =
  58.             PyString_AS_STRING((PyStringObject *)p->str) + newsize;
  59.         *p->ptr++ = c;
  60.     }
  61. }
  62.  
  63. static void
  64. w_string(s, n, p)
  65.     char *s;
  66.     int n;
  67.     WFILE *p;
  68. {
  69.     if (p->fp != NULL) {
  70.         fwrite(s, 1, n, p->fp);
  71.     }
  72.     else {
  73.         while (--n >= 0) {
  74.             w_byte(*s, p);
  75.             s++;
  76.         }
  77.     }
  78. }
  79.  
  80. static void
  81. w_short(x, p)
  82.     int x;
  83.     WFILE *p;
  84. {
  85.     w_byte( x      & 0xff, p);
  86.     w_byte((x>> 8) & 0xff, p);
  87. }
  88.  
  89. static void
  90. w_long(x, p)
  91.     long x;
  92.     WFILE *p;
  93. {
  94.     w_byte((int)( x      & 0xff), p);
  95.     w_byte((int)((x>> 8) & 0xff), p);
  96.     w_byte((int)((x>>16) & 0xff), p);
  97.     w_byte((int)((x>>24) & 0xff), p);
  98. }
  99.  
  100. #if SIZEOF_LONG > 4
  101. static void
  102. w_long64(x, p)
  103.     long x;
  104.     WFILE *p;
  105. {
  106.     w_long(x, p);
  107.     w_long(x>>32, p);
  108. }
  109. #endif
  110.  
  111. static void
  112. w_object(v, p)
  113.     PyObject *v;
  114.     WFILE *p;
  115. {
  116.     int i, n;
  117.     PyBufferProcs *pb;
  118.     
  119.     if (v == NULL) {
  120.         w_byte(TYPE_NULL, p);
  121.     }
  122.     else if (v == Py_None) {
  123.         w_byte(TYPE_NONE, p);
  124.     }
  125.     else if (v == Py_Ellipsis) {
  126.             w_byte(TYPE_ELLIPSIS, p);
  127.     }
  128.     else if (PyInt_Check(v)) {
  129.         long x = PyInt_AS_LONG((PyIntObject *)v);
  130. #if SIZEOF_LONG > 4
  131.         long y = x>>31;
  132.         if (y && y != -1) {
  133.             w_byte(TYPE_INT64, p);
  134.             w_long64(x, p);
  135.         }
  136.         else
  137. #endif
  138.             {
  139.             w_byte(TYPE_INT, p);
  140.             w_long(x, p);
  141.         }
  142.     }
  143.     else if (PyLong_Check(v)) {
  144.         PyLongObject *ob = (PyLongObject *)v;
  145.         w_byte(TYPE_LONG, p);
  146.         n = ob->ob_size;
  147.         w_long((long)n, p);
  148.         if (n < 0)
  149.             n = -n;
  150.         for (i = 0; i < n; i++)
  151.             w_short(ob->ob_digit[i], p);
  152.     }
  153.     else if (PyFloat_Check(v)) {
  154.         extern void PyFloat_AsString
  155.             Py_PROTO((char *, PyFloatObject *));
  156.         char buf[256]; /* Plenty to format any double */
  157.         PyFloat_AsString(buf, (PyFloatObject *)v);
  158.         n = strlen(buf);
  159.         w_byte(TYPE_FLOAT, p);
  160.         w_byte(n, p);
  161.         w_string(buf, n, p);
  162.     }
  163. #ifndef WITHOUT_COMPLEX
  164.     else if (PyComplex_Check(v)) {
  165.         extern void PyFloat_AsString
  166.             Py_PROTO((char *, PyFloatObject *));
  167.         char buf[256]; /* Plenty to format any double */
  168.         PyFloatObject *temp;
  169.         w_byte(TYPE_COMPLEX, p);
  170.         temp = (PyFloatObject*)PyFloat_FromDouble(
  171.             PyComplex_RealAsDouble(v));
  172.         PyFloat_AsString(buf, temp);
  173.         Py_DECREF(temp);
  174.         n = strlen(buf);
  175.         w_byte(n, p);
  176.         w_string(buf, n, p);
  177.         temp = (PyFloatObject*)PyFloat_FromDouble(
  178.             PyComplex_ImagAsDouble(v));
  179.         PyFloat_AsString(buf, temp);
  180.         Py_DECREF(temp);
  181.         n = strlen(buf);
  182.         w_byte(n, p);
  183.         w_string(buf, n, p);
  184.     }
  185. #endif
  186.     else if (PyString_Check(v)) {
  187.         w_byte(TYPE_STRING, p);
  188.         n = PyString_GET_SIZE(v);
  189.         w_long((long)n, p);
  190.         w_string(PyString_AS_STRING(v), n, p);
  191.     }
  192.     else if (PyUnicode_Check(v)) {
  193.             PyObject *utf8;
  194.         utf8 = PyUnicode_AsUTF8String(v);
  195.         if (utf8 == NULL) {
  196.             p->error = 1;
  197.             return;
  198.         }
  199.         w_byte(TYPE_UNICODE, p);
  200.         n = PyString_GET_SIZE(utf8);
  201.         w_long((long)n, p);
  202.         w_string(PyString_AS_STRING(utf8), n, p);
  203.         Py_DECREF(utf8);
  204.     }
  205.     else if (PyTuple_Check(v)) {
  206.         w_byte(TYPE_TUPLE, p);
  207.         n = PyTuple_Size(v);
  208.         w_long((long)n, p);
  209.         for (i = 0; i < n; i++) {
  210.             w_object(PyTuple_GET_ITEM(v, i), p);
  211.         }
  212.     }
  213.     else if (PyList_Check(v)) {
  214.         w_byte(TYPE_LIST, p);
  215.         n = PyList_GET_SIZE(v);
  216.         w_long((long)n, p);
  217.         for (i = 0; i < n; i++) {
  218.             w_object(PyList_GET_ITEM(v, i), p);
  219.         }
  220.     }
  221.     else if (PyDict_Check(v)) {
  222.         int pos;
  223.         PyObject *key, *value;
  224.         w_byte(TYPE_DICT, p);
  225.         /* This one is NULL object terminated! */
  226.         pos = 0;
  227.         while (PyDict_Next(v, &pos, &key, &value)) {
  228.             w_object(key, p);
  229.             w_object(value, p);
  230.         }
  231.         w_object((PyObject *)NULL, p);
  232.     }
  233.     else if (PyCode_Check(v)) {
  234.         PyCodeObject *co = (PyCodeObject *)v;
  235.         w_byte(TYPE_CODE, p);
  236.         w_short(co->co_argcount, p);
  237.         w_short(co->co_nlocals, p);
  238.         w_short(co->co_stacksize, p);
  239.         w_short(co->co_flags, p);
  240.         w_object(co->co_code, p);
  241.         w_object(co->co_consts, p);
  242.         w_object(co->co_names, p);
  243.         w_object(co->co_varnames, p);
  244.         w_object(co->co_filename, p);
  245.         w_object(co->co_name, p);
  246.         w_short(co->co_firstlineno, p);
  247.         w_object(co->co_lnotab, p);
  248.     }
  249.     else if ((pb = v->ob_type->tp_as_buffer) != NULL &&
  250.          pb->bf_getsegcount != NULL &&
  251.          pb->bf_getreadbuffer != NULL &&
  252.          (*pb->bf_getsegcount)(v, NULL) == 1)
  253.     {
  254.         /* Write unknown buffer-style objects as a string */
  255.         char *s;
  256.         w_byte(TYPE_STRING, p);
  257.         n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
  258.         w_long((long)n, p);
  259.         w_string(s, n, p);
  260.     }
  261.     else {
  262.         w_byte(TYPE_UNKNOWN, p);
  263.         p->error = 1;
  264.     }
  265. }
  266.  
  267. void
  268. PyMarshal_WriteLongToFile(x, fp)
  269.     long x;
  270.     FILE *fp;
  271. {
  272.     WFILE wf;
  273.     wf.fp = fp;
  274.     wf.error = 0;
  275.     w_long(x, &wf);
  276. }
  277.  
  278. void
  279. PyMarshal_WriteObjectToFile(x, fp)
  280.     PyObject *x;
  281.     FILE *fp;
  282. {
  283.     WFILE wf;
  284.     wf.fp = fp;
  285.     wf.error = 0;
  286.     w_object(x, &wf);
  287. }
  288.  
  289. typedef WFILE RFILE; /* Same struct with different invariants */
  290.  
  291. #include "protos/marshal2.h"
  292.  
  293. #define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
  294.  
  295. #define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
  296.  
  297. static int
  298. r_string(s, n, p)
  299.     char *s;
  300.     int n;
  301.     RFILE *p;
  302. {
  303.     if (p->fp != NULL)
  304.         return fread(s, 1, n, p->fp);
  305.     if (p->end - p->ptr < n)
  306.         n = p->end - p->ptr;
  307.     memcpy(s, p->ptr, n);
  308.     p->ptr += n;
  309.     return n;
  310. }
  311.  
  312. static int
  313. r_short(p)
  314.     RFILE *p;
  315. {
  316.     register short x;
  317.     x = r_byte(p);
  318.     x |= r_byte(p) << 8;
  319.     /* XXX If your short is > 16 bits, add sign-extension here!!! */
  320.     return x;
  321. }
  322.  
  323. static long
  324. r_long(p)
  325.     RFILE *p;
  326. {
  327.     register long x;
  328.     register FILE *fp = p->fp;
  329.     if (fp) {
  330.         x = getc(fp);
  331.         x |= (long)getc(fp) << 8;
  332.         x |= (long)getc(fp) << 16;
  333.         x |= (long)getc(fp) << 24;
  334.     }
  335.     else {
  336.         x = rs_byte(p);
  337.         x |= (long)rs_byte(p) << 8;
  338.         x |= (long)rs_byte(p) << 16;
  339.         x |= (long)rs_byte(p) << 24;
  340.     }
  341. #if SIZEOF_LONG > 4
  342.     /* Sign extension for 64-bit machines */
  343.     x <<= (8*sizeof(long) - 32);
  344.     x >>= (8*sizeof(long) - 32);
  345. #endif
  346.     return x;
  347. }
  348.  
  349. static long
  350. r_long64(p)
  351.     RFILE *p;
  352. {
  353.     register long x;
  354.     x = r_long(p);
  355. #if SIZEOF_LONG > 4
  356.     x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
  357. #else
  358.     if (r_long(p) != 0) {
  359.         PyObject *f = PySys_GetObject("stderr");
  360.         if (f != NULL)
  361.             (void) PyFile_WriteString(
  362.                 "Warning: un-marshal 64-bit int in 32-bit mode\n",
  363.                 f);
  364.     }
  365. #endif
  366.     return x;
  367. }
  368.  
  369. static PyObject *
  370. r_object(p)
  371.     RFILE *p;
  372. {
  373.     PyObject *v, *v2;
  374.     long i, n;
  375.     int type = r_byte(p);
  376.     
  377.     switch (type) {
  378.     
  379.     case EOF:
  380.         PyErr_SetString(PyExc_EOFError,
  381.                 "EOF read where object expected");
  382.         return NULL;
  383.     
  384.     case TYPE_NULL:
  385.         return NULL;
  386.     
  387.     case TYPE_NONE:
  388.         Py_INCREF(Py_None);
  389.         return Py_None;
  390.     
  391.     case TYPE_ELLIPSIS:
  392.         Py_INCREF(Py_Ellipsis);
  393.         return Py_Ellipsis;
  394.     
  395.     case TYPE_INT:
  396.         return PyInt_FromLong(r_long(p));
  397.     
  398.     case TYPE_INT64:
  399.         return PyInt_FromLong(r_long64(p));
  400.     
  401.     case TYPE_LONG:
  402.         {
  403.             int size;
  404.             PyLongObject *ob;
  405.             n = r_long(p);
  406.             size = n<0 ? -n : n;
  407.             ob = _PyLong_New(size);
  408.             if (ob == NULL)
  409.                 return NULL;
  410.             ob->ob_size = n;
  411.             for (i = 0; i < size; i++)
  412.                 ob->ob_digit[i] = r_short(p);
  413.             return (PyObject *)ob;
  414.         }
  415.     
  416.     case TYPE_FLOAT:
  417.         {
  418.             extern double atof Py_PROTO((const char *));
  419.             char buf[256];
  420.             double dx;
  421.             n = r_byte(p);
  422.             if (r_string(buf, (int)n, p) != n) {
  423.                 PyErr_SetString(PyExc_EOFError,
  424.                     "EOF read where object expected");
  425.                 return NULL;
  426.             }
  427.             buf[n] = '\0';
  428.             PyFPE_START_PROTECT("atof", return 0)
  429.             dx = atof(buf);
  430.             PyFPE_END_PROTECT(dx)
  431.             return PyFloat_FromDouble(dx);
  432.         }
  433.     
  434. #ifndef WITHOUT_COMPLEX
  435.     case TYPE_COMPLEX:
  436.         {
  437.             extern double atof Py_PROTO((const char *));
  438.             char buf[256];
  439.             Py_complex c;
  440.             n = r_byte(p);
  441.             if (r_string(buf, (int)n, p) != n) {
  442.                 PyErr_SetString(PyExc_EOFError,
  443.                     "EOF read where object expected");
  444.                 return NULL;
  445.             }
  446.             buf[n] = '\0';
  447.             PyFPE_START_PROTECT("atof", return 0)
  448.             c.real = atof(buf);
  449.             PyFPE_END_PROTECT(c)
  450.             n = r_byte(p);
  451.             if (r_string(buf, (int)n, p) != n) {
  452.                 PyErr_SetString(PyExc_EOFError,
  453.                     "EOF read where object expected");
  454.                 return NULL;
  455.             }
  456.             buf[n] = '\0';
  457.             PyFPE_START_PROTECT("atof", return 0)
  458.             c.imag = atof(buf);
  459.             PyFPE_END_PROTECT(c)
  460.             return PyComplex_FromCComplex(c);
  461.         }
  462. #endif
  463.     
  464.     case TYPE_STRING:
  465.         n = r_long(p);
  466.         if (n < 0) {
  467.             PyErr_SetString(PyExc_ValueError, "bad marshal data");
  468.             return NULL;
  469.         }
  470.         v = PyString_FromStringAndSize((char *)NULL, n);
  471.         if (v != NULL) {
  472.             if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
  473.                 Py_DECREF(v);
  474.                 v = NULL;
  475.                 PyErr_SetString(PyExc_EOFError,
  476.                     "EOF read where object expected");
  477.             }
  478.         }
  479.         return v;
  480.     
  481.     case TYPE_UNICODE:
  482.         {
  483.         char *buffer;
  484.  
  485.         n = r_long(p);
  486.         if (n < 0) {
  487.             PyErr_SetString(PyExc_ValueError, "bad marshal data");
  488.             return NULL;
  489.         }
  490.         buffer = PyMem_NEW(char, n);
  491.         if (buffer == NULL)
  492.             return PyErr_NoMemory();
  493.         if (r_string(buffer, (int)n, p) != n) {
  494.             PyMem_DEL(buffer);
  495.             PyErr_SetString(PyExc_EOFError,
  496.                 "EOF read where object expected");
  497.             return NULL;
  498.         }
  499.         v = PyUnicode_DecodeUTF8(buffer, n, NULL);
  500.         PyMem_DEL(buffer);
  501.         return v;
  502.         }
  503.         
  504.     case TYPE_TUPLE:
  505.         n = r_long(p);
  506.         if (n < 0) {
  507.             PyErr_SetString(PyExc_ValueError, "bad marshal data");
  508.             return NULL;
  509.         }
  510.         v = PyTuple_New((int)n);
  511.         if (v == NULL)
  512.             return v;
  513.         for (i = 0; i < n; i++) {
  514.             v2 = r_object(p);
  515.             if ( v2 == NULL ) {
  516.                 Py_DECREF(v);
  517.                 v = NULL;
  518.                 break;
  519.             }
  520.             PyTuple_SET_ITEM(v, (int)i, v2);
  521.         }
  522.         return v;
  523.     
  524.     case TYPE_LIST:
  525.         n = r_long(p);
  526.         if (n < 0) {
  527.             PyErr_SetString(PyExc_ValueError, "bad marshal data");
  528.             return NULL;
  529.         }
  530.         v = PyList_New((int)n);
  531.         if (v == NULL)
  532.             return v;
  533.         for (i = 0; i < n; i++) {
  534.             v2 = r_object(p);
  535.             if ( v2 == NULL ) {
  536.                 Py_DECREF(v);
  537.                 v = NULL;
  538.                 break;
  539.             }
  540.             PyList_SetItem(v, (int)i, v2);
  541.         }
  542.         return v;
  543.     
  544.     case TYPE_DICT:
  545.         v = PyDict_New();
  546.         if (v == NULL)
  547.             return NULL;
  548.         for (;;) {
  549.             PyObject *key, *val;
  550.             key = r_object(p);
  551.             if (key == NULL)
  552.                 break; /* XXX Assume TYPE_NULL, not an error */
  553.             val = r_object(p);
  554.             if (val != NULL)
  555.                 PyDict_SetItem(v, key, val);
  556.             Py_DECREF(key);
  557.             Py_XDECREF(val);
  558.         }
  559.         return v;
  560.     
  561.     case TYPE_CODE:
  562.         {
  563.             int argcount = r_short(p);
  564.             int nlocals = r_short(p);
  565.             int stacksize = r_short(p);
  566.             int flags = r_short(p);
  567.             PyObject *code = NULL;
  568.             PyObject *consts = NULL;
  569.             PyObject *names = NULL;
  570.             PyObject *varnames = NULL;
  571.             PyObject *filename = NULL;
  572.             PyObject *name = NULL;
  573.             int firstlineno = 0;
  574.             PyObject *lnotab = NULL;
  575.             
  576.             code = r_object(p);
  577.             if (code) consts = r_object(p);
  578.             if (consts) names = r_object(p);
  579.             if (names) varnames = r_object(p);
  580.             if (varnames) filename = r_object(p);
  581.             if (filename) name = r_object(p);
  582.             if (name) {
  583.                 firstlineno = r_short(p);
  584.                 lnotab = r_object(p);
  585.             }
  586.             
  587.             if (!PyErr_Occurred()) {
  588.                 v = (PyObject *) PyCode_New(
  589.                     argcount, nlocals, stacksize, flags, 
  590.                     code, consts, names, varnames,
  591.                     filename, name, firstlineno, lnotab);
  592.             }
  593.             else
  594.                 v = NULL;
  595.             Py_XDECREF(code);
  596.             Py_XDECREF(consts);
  597.             Py_XDECREF(names);
  598.             Py_XDECREF(varnames);
  599.             Py_XDECREF(filename);
  600.             Py_XDECREF(name);
  601.             Py_XDECREF(lnotab);
  602.  
  603.         }
  604.         return v;
  605.     
  606.     default:
  607.         /* Bogus data got written, which isn't ideal.
  608.            This will let you keep working and recover. */
  609.         PyErr_SetString(PyExc_ValueError, "bad marshal data");
  610.         return NULL;
  611.     
  612.     }
  613. }
  614.  
  615. long
  616. PyMarshal_ReadLongFromFile(fp)
  617.     FILE *fp;
  618. {
  619.     RFILE rf;
  620.     rf.fp = fp;
  621.     return r_long(&rf);
  622. }
  623.  
  624. PyObject *
  625. PyMarshal_ReadObjectFromFile(fp)
  626.     FILE *fp;
  627. {
  628.     RFILE rf;
  629.     if (PyErr_Occurred()) {
  630.         fprintf(stderr, "XXX rd_object called with exception set\n");
  631.         return NULL;
  632.     }
  633.     rf.fp = fp;
  634.     return r_object(&rf);
  635. }
  636.  
  637. PyObject *
  638. PyMarshal_ReadObjectFromString(str, len)
  639.     char *str;
  640.     int len;
  641. {
  642.     RFILE rf;
  643.     if (PyErr_Occurred()) {
  644.         fprintf(stderr, "XXX rds_object called with exception set\n");
  645.         return NULL;
  646.     }
  647.     rf.fp = NULL;
  648.     rf.str = NULL;
  649.     rf.ptr = str;
  650.     rf.end = str + len;
  651.     return r_object(&rf);
  652. }
  653.  
  654. PyObject *
  655. PyMarshal_WriteObjectToString(x) /* wrs_object() */
  656.     PyObject *x;
  657. {
  658.     WFILE wf;
  659.     wf.fp = NULL;
  660.     wf.str = PyString_FromStringAndSize((char *)NULL, 50);
  661.     if (wf.str == NULL)
  662.         return NULL;
  663.     wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
  664.     wf.end = wf.ptr + PyString_Size(wf.str);
  665.     wf.error = 0;
  666.     w_object(x, &wf);
  667.     if (wf.str != NULL)
  668.         _PyString_Resize(&wf.str,
  669.             (int) (wf.ptr -
  670.                PyString_AS_STRING((PyStringObject *)wf.str)));
  671.     if (wf.error) {
  672.         Py_XDECREF(wf.str);
  673.         PyErr_SetString(PyExc_ValueError, "unmarshallable object");
  674.         return NULL;
  675.     }
  676.     return wf.str;
  677. }
  678.  
  679. /* And an interface for Python programs... */
  680.  
  681. static PyObject *
  682. marshal_dump(self, args)
  683.     PyObject *self;
  684.     PyObject *args;
  685. {
  686.     WFILE wf;
  687.     PyObject *x;
  688.     PyObject *f;
  689.     if (!PyArg_ParseTuple(args, "OO:dump", &x, &f))
  690.         return NULL;
  691.     if (!PyFile_Check(f)) {
  692.         PyErr_SetString(PyExc_TypeError,
  693.                 "marshal.dump() 2nd arg must be file");
  694.         return NULL;
  695.     }
  696.     wf.fp = PyFile_AsFile(f);
  697.     wf.str = NULL;
  698.     wf.ptr = wf.end = NULL;
  699.     wf.error = 0;
  700.     w_object(x, &wf);
  701.     if (wf.error) {
  702.         PyErr_SetString(PyExc_ValueError, "unmarshallable object");
  703.         return NULL;
  704.     }
  705.     Py_INCREF(Py_None);
  706.     return Py_None;
  707. }
  708.  
  709. static PyObject *
  710. marshal_load(self, args)
  711.     PyObject *self;
  712.     PyObject *args;
  713. {
  714.     RFILE rf;
  715.     PyObject *f;
  716.     PyObject *v;
  717.     if (!PyArg_ParseTuple(args, "O:load", &f))
  718.         return NULL;
  719.     if (!PyFile_Check(f)) {
  720.         PyErr_SetString(PyExc_TypeError,
  721.                 "marshal.load() arg must be file");
  722.         return NULL;
  723.     }
  724.     rf.fp = PyFile_AsFile(f);
  725.     rf.str = NULL;
  726.     rf.ptr = rf.end = NULL;
  727.     PyErr_Clear();
  728.     v = r_object(&rf);
  729.     if (PyErr_Occurred()) {
  730.         Py_XDECREF(v);
  731.         v = NULL;
  732.     }
  733.     return v;
  734. }
  735.  
  736. static PyObject *
  737. marshal_dumps(self, args)
  738.     PyObject *self;
  739.     PyObject *args;
  740. {
  741.     PyObject *x;
  742.     if (!PyArg_ParseTuple(args, "O:dumps", &x))
  743.         return NULL;
  744.     return PyMarshal_WriteObjectToString(x);
  745. }
  746.  
  747. static PyObject *
  748. marshal_loads(self, args)
  749.     PyObject *self;
  750.     PyObject *args;
  751. {
  752.     RFILE rf;
  753.     PyObject *v;
  754.     char *s;
  755.     int n;
  756.     if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
  757.         return NULL;
  758.     rf.fp = NULL;
  759.     rf.str = args;
  760.     rf.ptr = s;
  761.     rf.end = s + n;
  762.     PyErr_Clear();
  763.     v = r_object(&rf);
  764.     if (PyErr_Occurred()) {
  765.         Py_XDECREF(v);
  766.         v = NULL;
  767.     }
  768.     return v;
  769. }
  770.  
  771. static PyMethodDef marshal_methods[] = {
  772.     {"dump",    marshal_dump,    1},
  773.     {"load",    marshal_load,    1},
  774.     {"dumps",    marshal_dumps,    1},
  775.     {"loads",    marshal_loads,    1},
  776.     {NULL,        NULL}        /* sentinel */
  777. };
  778.  
  779. void
  780. PyMarshal_Init()
  781. {
  782.     (void) Py_InitModule("marshal", marshal_methods);
  783. }
  784.